package no.sachmuld.methodcombination.examples.adapter.aopstyle;

import no.sachmuld.methodcombination.api.BehaviourChain;
import no.sachmuld.methodcombination.api.CrosscuttingBehaviour;
import no.sachmuld.methodcombination.api.MethodInvocation;
import no.sachmuld.methodcombination.api.adapter.Crosscutting;

/**
 *
 */
public abstract class Foo {

    private BehaviourChain<CrosscuttingBehaviour> chain = new BehaviourChain<>();

    final public String bar(final int i) {

        return new Crosscutting<CrosscuttingBehaviour, String>(chain) {

            @Override
            protected String executePrimary(CrosscuttingBehaviour behaviour, MethodInvocation<String> methodInvocation) {
                if (behaviour instanceof FooBehaviour) {
                    FooBehaviour fooBehaviour = (FooBehaviour) behaviour;
                    return fooBehaviour.bar(i, methodInvocation);
                } else {
                    return methodInvocation.proceed();
                }
            }

        }.execute();
    }

    final public String baz(final int i) {
        return new Crosscutting<CrosscuttingBehaviour, String>(chain) {

            @Override
            protected String executePrimary(CrosscuttingBehaviour behaviour, MethodInvocation<String> methodInvocation) {
                if (behaviour instanceof FooBehaviour) {
                    FooBehaviour fooBehaviour = (FooBehaviour) behaviour;
                    return fooBehaviour.baz(i, methodInvocation);
                } else {
                    return methodInvocation.proceed();
                }
            }

        }.execute();
    }

    final protected Foo with(CrosscuttingBehaviour... behaviours) {
        chain.addAll(behaviours);
        return this;
    }
}
